'''
Created on Jan 18, 2010

@author: madsk
'''

from PyQt4 import QtCore, QtGui
from common.overlays import NextButton, PreviousButton, FullScreenButton, EditButton, MonitorButton
from common import GraphicsScene, MultiImage
import os

class GraphicsView(QtGui.QGraphicsView):
    # Signals.
    toggleFullScreen = QtCore.pyqtSignal()
    modeChange = QtCore.pyqtSignal(str)
    
    FULLSCREEN = QtCore.QRectF(0, 0, 800, 480)
    WINDOWED = QtCore.QRectF(0, 0, 800, 424)
    
    def __init__(self, imageloader, parent=None):
        super(QtGui.QGraphicsView, self).__init__(parent)
        self._imageloader = imageloader
        self._fullscreen = None
        self._temporaryOverlays = []
        
        # Build a scene.
        self._scene = GraphicsScene(self)
        self._pixmapitem = None
        self._textitem = None
        self.setScene(self._scene)
        self._scene.clicked.connect(lambda: self._showOverlay('scene-clicked'))
        
        # Remove scrollbars.
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        # Add the overlay buttons.
        self._nextbutton = NextButton()
        self._scene.addItem(self._nextbutton)
        self._nextbutton.setZValue(1)
        self._nextbutton.clicked.connect(self._handleNextClicked)
        
        self._previousbutton = PreviousButton()
        self._scene.addItem(self._previousbutton)
        self._previousbutton.setZValue(1)
        self._previousbutton.clicked.connect(self._handlePreviousClicked)
        
        self._fullscreenbutton = FullScreenButton()
        self._scene.addItem(self._fullscreenbutton)
        self._fullscreenbutton.setZValue(1)
        self._fullscreenbutton.clicked.connect(self._handleFullScreenClicked)
        self._fullscreenbutton.setVisible(False)

        self._editbutton = EditButton()
        self._scene.addItem(self._editbutton)
        self._editbutton.setZValue(1)
        self._editbutton.clicked.connect(self._handleEditClicked)
        self._editbutton.setVisible(False)
        
        self._monitorbutton = MonitorButton()
        self._scene.addItem(self._monitorbutton)
        self._monitorbutton.setZValue(1)
        self._monitorbutton.clicked.connect(self._handleMonitorClicked)
        self._monitorbutton.setVisible(False)
        
        self._timer = QtCore.QTimer()
        self._timer.setSingleShot(True)
        self._timer.setInterval(2000)
        self._timer.timeout.connect(self._hideTemporaryButtons)
       
        # Add the first image to the scene.
        if self._imageloader.has_current():
            image_path, image_pixmap = self._imageloader.current()
            if image_pixmap != None:
                self.setImage(image_pixmap)
            else:
                self.setText('Unable to load %s'%os.path.basename(image_path))
        else:
            self.setText('No images found.')

    def setFullScreen(self, fullscreen):
        self._fullscreen = fullscreen
        if fullscreen == True:
            self._scene.setSceneRect(GraphicsView.FULLSCREEN)
            self._nextbutton.setPos(690, 190)
            self._previousbutton.setPos(10, 190)
            self._fullscreenbutton.setPos(690, 370)
            self._editbutton.setPos(350, 370)
            self._monitorbutton.setPos(690, 10)
        else:
            self._scene.setSceneRect(GraphicsView.WINDOWED)
            self._nextbutton.setPos(690, 162)
            self._previousbutton.setPos(10, 162)
            self._fullscreenbutton.setPos(690, 314)
            self._editbutton.setPos(350, 314)
            self._monitorbutton.setPos(690, 10)
        self._positionImage()
    
    def setImage(self, pixmap):
        # Remove the old text.
        if self._textitem:
            self._scene.removeItem(self._textitem)
            self._textitem = None

        # Remove the old image.
        if self._pixmapitem:
            self._scene.removeItem(self._pixmapitem)
            self._pixmapitem = None
            
        # Add and position the new one.
        self._pixmapitem = self._scene.addPixmap(pixmap)
        self._positionImage()
        
        # Modify the overlay.
        self._setOverlay()
        
    def setText(self, message):
        # Remove the old text.
        if self._textitem:
            self._scene.removeItem(self._textitem)
            self._textitem = None

        # Remove the old image.
        if self._pixmapitem:
            self._scene.removeItem(self._pixmapitem)
            self._pixmapitem = None
            
        # Add and position the new text message.
        self._textitem = self._scene.addText(message)
        self._textitem.setDefaultTextColor(QtGui.QColor(255,255,255))
        textsize = self._textitem.boundingRect()
        canvassize = GraphicsView.FULLSCREEN if self._fullscreen else GraphicsView.WINDOWED
        self._textitem.setPos((canvassize.width() - textsize.width()) / 2,
                              (canvassize.height() - textsize.height()) / 2)

        # Modify the overlay.
        self._setOverlay()

    def _positionImage(self):
        if self._pixmapitem:
            imagesize = self._pixmapitem.boundingRect()
            canvassize = GraphicsView.FULLSCREEN if self._fullscreen else GraphicsView.WINDOWED
            self._pixmapitem.setPos((canvassize.width() - imagesize.width()) / 2,
                                    (canvassize.height() - imagesize.height()) / 2)
            
    def _setOverlay(self):
        self._nextbutton.setVisible(self._imageloader.has_next())
        self._previousbutton.setVisible(self._imageloader.has_previous())
                
    def _handleNextClicked(self):
        if self._imageloader.has_next():
            image_path, image_pixmap = self._imageloader.next()
            if image_pixmap != None:
                self.setImage(image_pixmap)
            else:
                self.setText('Unable to load %s'%os.path.basename(image_path))
        
    def _handlePreviousClicked(self):
        if self._imageloader.has_previous():
            image_path, image_pixmap = self._imageloader.previous()
            if image_pixmap != None:
                self.setImage(image_pixmap)
            else:
                self.setText('Unable to load %s'%os.path.basename(image_path))
            
    def _handleFullScreenClicked(self):
        self._timer.stop()
        self._hideTemporaryButtons()
        self.toggleFullScreen.emit()
        
    def _handleEditClicked(self):
        self._timer.stop()
        self._hideTemporaryButtons()
        self.modeChange.emit('Editor')
        
    def _handleMonitorClicked(self):
        self._timer.stop()
        self._hideTemporaryButtons()
        self.modeChange.emit('Monitor')
        
    def _showOverlay(self, group):
        self._timer.stop()
        self._hideTemporaryButtons()
        if group == 'scene-clicked':
            self._displayTemporaryButtons(self._editbutton, self._fullscreenbutton, self._monitorbutton)
        self._timer.start()
            
    def _displayTemporaryButtons(self, *buttons):
        for button in buttons:
            button.setVisible(True)
            self._temporaryOverlays.append(button)
    
    def _hideTemporaryButtons(self):
        while len(self._temporaryOverlays) > 0:
            button = self._temporaryOverlays.pop()
            button.setVisible(False)
